import { ModdleElement } from 'bpmn-moddle'
import { getBusinessObject, is } from 'bpmn-js/lib/util/ModelUtil'
import { useSettingStore } from '@/store/bpmnProcess/settingStore'
import { useModelerStore } from '@/store/bpmnProcess/modelerStore'
import { getTimerEventDefinition } from './bpmnPropertyUtils/eventDefinition'
import { isAsync } from './bpmnPropertyUtils/asyncElement'
import { createModdleElement, getExtensionElementsList } from './bpmnPropertyUtils/extensionElements'

//
export function retryTimeCycleVisible(element): boolean {
  const prefix = useSettingStore().editor.processEngine
  const businessObject = getBusinessObject(element)
  return (is(element, `${prefix}:AsyncCapable`) && isAsync(businessObject)) || !!isTimerEvent(element)
}
export function jobPriorityVisible(element): boolean {
  const prefix = useSettingStore().editor.processEngine
  const businessObject = getBusinessObject(element)
  return (is(element, `${prefix}:JobPriorized`) && isAsync(businessObject)) || is(element, 'bpmn:Process') || (is(element, 'bpmn:Participant') && businessObject.get('processRef')) || !!isTimerEvent(element)
}
export function isJobExecutable(element): boolean {
  return retryTimeCycleVisible(element) || jobPriorityVisible(element)
}

// 任务优先级
export function getJobPriorityValue(element): string | undefined {
  const prefix = useSettingStore().editor.processEngine
  const businessObject = getRelativeBusinessObject(element)
  return businessObject.get(`${prefix}:jobPriority`)
}
export function setJobPriorityValue(element, value: string | undefined) {
  const prefix = useSettingStore().editor.processEngine
  const modeling = useModelerStore().getModeling
  const businessObject = getRelativeBusinessObject(element)
  modeling.updateModdleProperties(element, businessObject, {
    [`${prefix}:jobPriority`]: value
  })
}

// 重试周期
export function getRetryTimeCycleValue(element): string | undefined {
  const prefix = useSettingStore().editor.processEngine
  const businessObject = getBusinessObject(element)
  const failedJobRetryTimeCycle = getExtensionElementsList(businessObject, `${prefix}:FailedJobRetryTimeCycle`)[0]
  return failedJobRetryTimeCycle && failedJobRetryTimeCycle.body
}
export function setRetryTimeCycleValue(element, value: string | undefined) {
  const prefix = useSettingStore().editor.processEngine
  const modeling = useModelerStore().getModeling
  const businessObject = getBusinessObject(element)

  let extensionElements = businessObject.get('extensionElements')
  if (!extensionElements) {
    extensionElements = createModdleElement('bpmn:ExtensionElements', { values: [] }, businessObject)
    modeling.updateModdleProperties(element, businessObject, { extensionElements })
  }

  let failedJobRetryTimeCycle = getExtensionElementsList(businessObject, `${prefix}:FailedJobRetryTimeCycle`)[0]
  if (!failedJobRetryTimeCycle) {
    failedJobRetryTimeCycle = createModdleElement(`${prefix}:FailedJobRetryTimeCycle`, {}, extensionElements)
    modeling.updateModdleProperties(element, extensionElements, {
      values: [...extensionElements.get('values'), failedJobRetryTimeCycle]
    })
  }

  modeling.updateModdleProperties(element, failedJobRetryTimeCycle, { body: value })
}

// ///////// helpers

function getRelativeBusinessObject(element): ModdleElement {
  let businessObject
  if (is(element, 'bpmn:Participant')) {
    businessObject = getBusinessObject(element).get('processRef')
  } else {
    businessObject = getBusinessObject(element)
  }
  return businessObject
}

function isTimerEvent(element): ModdleElement | undefined | false {
  return is(element, 'bpmn:Event') && getTimerEventDefinition(element)
}
